from purest.web.resources.plainResource import PlainResource
from purest.web.request import Request
from purest.web import status
import mimetypes
import os

class FileResource(PlainResource):
    """ Serves static only from the given base_directory or its sub directories.
    
    The content type header depends on the file extension (like ".gif"). 
    """
    
    def __init__(self, base_directory):
        """ base_directory: absolute or relative path to the directory which
        containts the files (and sub directories)."""
        
        super().__init__()      
        self.base_directory = os.path.abspath(base_directory)            

    def get(self, environ, start_response):
        request = Request(environ)
        try:
            file_name = request.path_params["file"]
            absolute_path = os.path.join(self.base_directory, file_name)
            normalized_path = os.path.normpath(absolute_path)
            
            # security check to prevent directory traversal
            if not normalized_path.startswith(self.base_directory): 
                raise IOError()
            
            file_size =  os.path.getsize(normalized_path)
            file = open(normalized_path, "rb")
            mime_type = mimetypes.guess_type(normalized_path)[0]
            start_response(status.OK, 
                           [('Content-Type', mime_type), 
                            ('Content-Length', str(file_size))])
            return file
        except IOError:
            start_response(status.NOT_FOUND, 
                           [('Content-Type', 'text/plain; charset=UTF-8')])
            return ["File not found.".encode(encoding='utf_8', errors='strict')]
